#include "cameraanimationactor.h"
#include "datatypedefine.h"
#include "stringproperty.h"
#include <QStringList>
#include "numberproperty.h"

namespace VrDataCore
{
	CamreaAnimationBase::CamreaAnimationBase()
	{
		setClassName(CLASS_CAMERA_ANIMATION_BASE);
	}

	void CamreaAnimationBase::buildPropertyMap()
	{
		addProperty(new IntProperty<CamreaAnimationBase>(XML_ELEMENT_DATATYPE_INT,
			"Play Index","",this,&CamreaAnimationBase::setIndex,
			&CamreaAnimationBase::getIndex,"",""));
	}

	void CamreaAnimationBase::setIndex(int index)
	{
		_index = index;
	}

	int CamreaAnimationBase::getIndex()
	{
		return _index;
	}

	CamreaAnimationActor::CamreaAnimationActor()
	{
		setClassName(CLASS_CAMERA_ANIMATION);
	}

	CamreaAnimationActor::~CamreaAnimationActor()
	{}

	void CamreaAnimationActor::buildPropertyMap()
	{
		CamreaAnimationBase::buildPropertyMap();
		addProperty(new StringProperty<CamreaAnimationActor>(XML_ELEMENT_DATATYPE_STRING,
			"Camrea Attitude","",this,&CamreaAnimationActor::setCamreaAttitude,
			&CamreaAnimationActor::getCamreaAttitude,"",""));
		addProperty(new StringProperty<CamreaAnimationActor>(XML_ELEMENT_DATATYPE_STRING,
			"Frame Number","",this,&CamreaAnimationActor::setCamreaFrameNumber,
			&CamreaAnimationActor::getCamreaFrameNumber,"",""));
	}

	void CamreaAnimationActor::setCamreaAttitude(QString allattitude)
	{
		_allAttitudeString = allattitude;
		QStringList attitudelist = _allAttitudeString.split("|",QString::SkipEmptyParts);
		for(int i=0;i<attitudelist.size();++i)
		{
			QStringList everyattitude = attitudelist.at(i).split(",",QString::SkipEmptyParts);
			if(everyattitude.size() == 3)
			{
				QStringList eyelist = everyattitude.at(0).split(" ",QString::SkipEmptyParts);
				QStringList centerlist = everyattitude.at(1).split(" ",QString::SkipEmptyParts);
				QStringList uplist = everyattitude.at(2).split(" ",QString::SkipEmptyParts);
				QVector<osg::Vec3> attitudevec(3);
				attitudevec[0] = osg::Vec3(eyelist.at(0).toFloat(),eyelist.at(1).toFloat(),eyelist.at(2).toFloat());
				attitudevec[1] = osg::Vec3(centerlist.at(0).toFloat(),centerlist.at(1).toFloat(),centerlist.at(2).toFloat());
				attitudevec[2] = osg::Vec3(uplist.at(0).toFloat(),uplist.at(1).toFloat(),uplist.at(2).toFloat());
				_cameraAttitudeVector.push_back(attitudevec);
			}
		}
	}

	QString CamreaAnimationActor::getCamreaAttitude()
	{
		_allAttitudeString = "";
		for(int i=0;i<_cameraAttitudeVector.size();++i)
		{
			osg::Vec3 eye = _cameraAttitudeVector.at(i).at(0);
			osg::Vec3 center = _cameraAttitudeVector.at(i).at(1);
			osg::Vec3 up = _cameraAttitudeVector.at(i).at(2);
			_allAttitudeString = _allAttitudeString+"|";
			_allAttitudeString = _allAttitudeString + QString::number(eye.x()) + " "+QString::number(eye.y()) + " "+QString::number(eye.z());
			_allAttitudeString = _allAttitudeString+",";
			_allAttitudeString = _allAttitudeString + QString::number(center.x()) + " "+QString::number(center.y()) + " "+QString::number(center.z());
			_allAttitudeString = _allAttitudeString+",";
			_allAttitudeString = _allAttitudeString + QString::number(up.x()) + " "+QString::number(up.y()) + " "+QString::number(up.z());
		}
		return _allAttitudeString;
	}

	void CamreaAnimationActor::setCamreaFrameNumber(QString framenumberstring)
	{
		_frameNumberString = framenumberstring;
		QStringList framenumberlist = _frameNumberString.split(" ",QString::SkipEmptyParts);
		for(int i=0;i<framenumberlist.size();++i)
		{
			_frameNumberVector.push_back(framenumberlist.at(i).toInt());
		}
	}

	QString CamreaAnimationActor::getCamreaFrameNumber()
	{
		_frameNumberString = "";
		for(int i=0;i<_frameNumberVector.size();++i)
		{
			_frameNumberString = _frameNumberString+" ";
			_frameNumberString = _frameNumberString + QString::number(_frameNumberVector.at(i));
		}
		return _frameNumberString;
	}

	QVector<QVector<osg::Vec3>> CamreaAnimationActor::getCameraAttitudeVector()
	{
		return _cameraAttitudeVector;
	}

	QVector<int> CamreaAnimationActor::getFrameNumberVector()
	{
		return _frameNumberVector;
	}

	void CamreaAnimationActor::removeCameraAttitude(int index)
	{
		_cameraAttitudeVector.remove(index);
		if(index>0)
			_frameNumberVector.remove(index-1);
	}

	void CamreaAnimationActor::resetFrameNumber(int index,int framenumber)
	{
		if(index<0)
			return;
		_frameNumberVector[index] = framenumber;
	}

	void CamreaAnimationActor::addCameraAttitude(const osg::Vec3& eye,const osg::Vec3& center,const osg::Vec3& up,int framenumber)
	{
		QVector<osg::Vec3> newvector;
		newvector.push_back(eye);
		newvector.push_back(center);
		newvector.push_back(up);
		_cameraAttitudeVector.push_back(newvector);
		if(_cameraAttitudeVector.size()>1)
			_frameNumberVector.push_back(framenumber);
	}

	int CamreaAnimationActor::getFrameNumberByIndex(int index)
	{
		if(index<0)
			return 0;
		return _frameNumberVector[index];
	}

	ImpCamreaAnimationActor::ImpCamreaAnimationActor()
	{
		setClassName(CLASS_IMP_CAMERA_ANIMATION);
		_animationNode = new osg::AnimationPath;
	}

	ImpCamreaAnimationActor::~ImpCamreaAnimationActor()
	{}

	void ImpCamreaAnimationActor::buildPropertyMap()
	{
		CamreaAnimationBase::buildPropertyMap();
		addProperty(new StringProperty<ImpCamreaAnimationActor>(XML_ELEMENT_DATATYPE_STRING,
			"Time To Control Point","",this,&ImpCamreaAnimationActor::setCameraTimeControlPointMap,
			&ImpCamreaAnimationActor::getCameraTimeControlPointMap,"",""));
	}

	void ImpCamreaAnimationActor::setCameraAnimationControlMap(osg::AnimationPath::TimeControlPointMap& map)
	{
		if(map.size()>0)
		{
			osg::AnimationPath::TimeControlPointMap newmap;
			osg::AnimationPath::TimeControlPointMap::iterator iter = map.begin();
			newmap.insert(std::pair<double,osg::AnimationPath::ControlPoint>((*iter).first,(*iter).second));
			osg::AnimationPath::TimeControlPointMap::iterator preiter = iter;
			iter++;
			for(;iter!=map.end();++iter)
			{
				osg::AnimationPath::ControlPoint point = (*preiter).second;
				if(point.getPosition() == (*iter).second.getPosition() && point.getRotation() == (*iter).second.getRotation())
					continue;
				newmap.insert(std::pair<double,osg::AnimationPath::ControlPoint>((*iter).first,(*iter).second));
				preiter = iter;
			}
			_animationNode->setTimeControlPointMap(newmap);
		}
	}

	void ImpCamreaAnimationActor::setCameraTimeControlPointMap(QString data)
	{
		_animationNode->clear();
		QStringList datalist = data.split("|",QString::SkipEmptyParts);
		for(int i=0;i<datalist.size();++i)
		{
			QStringList everycontrol = datalist.at(i).split(" ",QString::SkipEmptyParts);
			double time = everycontrol.at(0).toDouble();
			osg::Vec3d pos;
			pos.x() = everycontrol.at(1).toDouble();
			pos.y() = everycontrol.at(2).toDouble();
			pos.z() = everycontrol.at(3).toDouble();
			osg::Quat q;
			q.x() = everycontrol.at(4).toDouble();
			q.y() = everycontrol.at(5).toDouble();
			q.z() = everycontrol.at(6).toDouble();
			q.w() = everycontrol.at(7).toDouble();
			osg::Vec3d scal;
			scal.x() = everycontrol.at(8).toDouble();
			scal.y() = everycontrol.at(9).toDouble();
			scal.z() = everycontrol.at(10).toDouble();
			_animationNode->insert(time,osg::AnimationPath::ControlPoint(pos,q));
		}
	}

	QString ImpCamreaAnimationActor::getCameraTimeControlPointMap()
	{
		QString returnstring = "";
		osg::AnimationPath::TimeControlPointMap map = _animationNode->getTimeControlPointMap();
		osg::AnimationPath::TimeControlPointMap::iterator iter = map.begin();
		for(;iter!=map.end();++iter)
		{
			QString everycontrol = QString::number((*iter).first,'g',15);
			osg::Vec3d pos = (*iter).second.getPosition();
			osg::Quat q = (*iter).second.getRotation();
			osg::Vec3d scal = (*iter).second.getScale();
			everycontrol = everycontrol+" "+QString::number(pos.x(),'g',15)+" "+QString::number(pos.y(),'g',15)+" "+QString::number(pos.z(),'g',15);
			everycontrol = everycontrol+" "+QString::number(q.x(),'g',15)+" "+QString::number(q.y(),'g',15)+" ";
			everycontrol = everycontrol+QString::number(q.z(),'g',15)+" "+QString::number(q.w(),'g',15);
			everycontrol = everycontrol+" "+QString::number(scal.x(),'g',15)+" "+QString::number(scal.y(),'g',15)+" "+QString::number(scal.z(),'g',15);
			returnstring = returnstring+"|"+everycontrol;
		}
		return returnstring;
	}

	osg::ref_ptr<osg::AnimationPath> ImpCamreaAnimationActor::getCameraAnimationPath()
	{
		return _animationNode;
	}
}